import json
from utils import log


# json.loads()函数是将json格式数据转换为字典（可以这么理解，json.loads()函数是将字符串转化为字典）
def load(path):
    with open(path, 'r', encoding='utf-8')as f:
        s = f.read()
        # log('load', s)
        return json.loads(s)


# json.dumps()函数是将一个Python数据类型列表data进行json格式的编码s（可以这么理解，json.dumps()函数是将字典转化为字符串）
def save(data, path):
    s = json.dumps(data, indent=2, ensure_ascii=False)
    with open(path, 'w+', encoding='utf-8')as f:
        # log('save', path, s, data)
        f.write(s)


class Model(object):
    @classmethod
    def db_path(cls):
        classname = cls.__name__
        path = 'db/{}.txt'.format(classname)
        return path

    # @classmethod
    # def new(cls, form):
    #     m = cls(form)
    #     return m

    @classmethod
    def all(cls):
        path = cls.db_path()
        models = load(path)
        # ms = [cls.new(m) for m in models]
        ms = [cls._new_from_dict(m) for m in models]
        # log('ms', ms)
        return ms

    def save(self):
        # log('debug save')
        models = self.all()
        # log('models', models)
        first_index = 0
        if self.__dict__.get('id') is None:
            if (len(models)) == 0:
                self.id = 1
            else:
                m = models[-1]
                self.id = m.id + 1
            models.append(self)
        else:
            index = -1
            for i, m in enumerate(models):
                if m.id == self.id:
                    index = i
                    break
            # if index > -1:
            models[index] = self
        l = [m.__dict__ for m in models]
        path = self.db_path()
        save(l, path)

    # 相当于cls.new(m).string()
    def __repr__(self):
        classname = self.__class__.__name__
        properties = ['{}:({})'.format(k, v) for k, v in self.__dict__.items()]
        s = '\n'.join(properties)
        return '< {}\n{} \n >\n'.format(classname, s)

    @classmethod
    def find_by(cls, **kwargs):
        log('kwargs, ', kwargs, type(kwargs))
        k, v = '', ''
        for key, value in kwargs.items():
            k, v = key, value
        all = cls.all()
        for m in all:
            if v == m.__dict__[k]:
                return m
        return None

    @classmethod
    def find_all(cls, **kwargs):
        log('kwargs, ', kwargs, type(kwargs))
        k, v = '', ''
        for key, value in kwargs.items():
            k, v = key, value
        all = cls.all()
        data = []
        for m in all:
            if v == m.__dict__[k]:
                data.append(m)
        return data

    @classmethod
    def find(cls, id):
        return cls.find_by(id=id)

    @classmethod
    def delete(cls, id):
        models = cls.all()
        index = -1
        for i, e in enumerate(models):
            if e.id == id:
                index = i
                break
        if index == -1:
            pass
        else:
            models.pop(index)
            l = [m.__dict__ for m in models]
            path = cls.db_path()
            save(l, path)
            return

    # 新增1
    @classmethod
    def _new_from_dict(cls, d):
        # 因为子元素的 __init__ 需要一个 form 参数
        # 所以这个给一个空字典
        m = cls({})
        for k, v in d.items():
            # setattr 是一个特殊的函数
            # 假设 k v 分别是 'name'  'gua'
            # 它相当于 m.name = 'gua'
            setattr(m, k, v)
        return m

    # 新增2
    def json(self):
        """
        返回当前 model 的字典表示
        """
        # copy 会复制一份新数据并返回
        d = self.__dict__.copy()
        return d
